package xyz.twj.fx

//import com.sun.javafx.webkit.WebConsoleListener
import javafx.concurrent.Worker
import javafx.scene.Scene
import javafx.scene.layout.HBox
import javafx.scene.web.WebEngine
import javafx.scene.web.WebView
import netscape.javascript.JSObject
import java.lang.RuntimeException


class WebViewScene : Scene {

    /**
     * 初始化控制台
     */
    companion object {
        init {
//            WebConsoleListener.setDefaultListener { webView, message, lineNumber, sourceId ->
//                println("Console:${webView.engine.title}- $message [$sourceId:$lineNumber]");
//            };
            System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
        }
    }

    val webView: WebView = WebView()
    val engine: WebEngine = webView.engine
    val loadWorker = engine.loadWorker
    val javaInterface = JavaInterface()
    val window: JSObject? = null

    constructor() : this(HBox())

    constructor(url: String) : this(HBox()) {
        engine.load(url)
    }

    private constructor(root: HBox) : super(root) {
        root.children.add(webView)

        loadWorker()

        engine.setOnStatusChanged { event ->
            println("$event")
        }
        engine.setOnError { event ->
            println("${event}")
        }
    }

    /**
     * 加载页面
     */
    fun loadUrl(url: String) {
        engine.load(url)
    }

    /**
     * 设置 window的属性，在VUE中监听这个属性，那么就可以实现状态想js传递
     */
    fun setState(obj: String, name: String, value: Any) {
        val jsObject = engine.executeScript("window.$obj")
        if (jsObject is JSObject) {
            jsObject.setMember(name, value)
        } else {
            throw RuntimeException("$obj is undefined")
        }
    }

    private fun initJsEnv() {
        val window = engine.executeScript("window") as JSObject
        window.setMember("java", javaInterface)
    }

    private fun loadWorker() {
        loadWorker.stateProperty().addListener { _, _, state ->
            when (state) {
                Worker.State.SUCCEEDED -> {
                    initJsEnv()
                    setState("data", "a", 6)
                    println("SUCCEEDED")
                }

                Worker.State.READY -> {
                    println("READY")
                }
                Worker.State.SCHEDULED -> {
                    println("SCHEDULED")
                }
                Worker.State.RUNNING -> {
                    println("RUNNING")
                }
                Worker.State.CANCELLED -> {
                    println("CANCELLED")
                }
                Worker.State.FAILED -> {
                    println("FAILED")
                }
                else -> {
                }
            }
        };
    }
}